package de.dlrg.wms.gui.forms;

import java.util.HashMap;
import java.util.Observable;

import javax.validation.ConstraintViolationException;

import org.eclipse.swt.widgets.Composite;

import de.dlrg.wms.controller.controllers.AgeClassController;
import de.dlrg.wms.controller.controllers.ConnectivityDeviceController;
import de.dlrg.wms.controller.controllers.TrackController;
import de.dlrg.wms.gui.forms.generic.GenericForm;
import de.dlrg.wms.interfaces.controller.IDeviceController;
import de.dlrg.wms.interfaces.controller.IDeviceControllerCallback;
import de.dlrg.wms.model.Track;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Spinner;

import wms2010.interfaces.devices.IDevice;

public class TrackForm extends GenericForm implements IDeviceControllerCallback {
	private Composite shell;
	private static int START_DISCOVERY_INDEX = 0;
	private final Spinner trackNo;
	private ConnectivityDeviceController connectivityDeviceController;
	private TrackController trackController;
	private Track trackToWorkOn;
	private Combo connectivities;
	private final Combo devices;
	private HashMap<Integer, IDeviceController> indexIDeviceControllerMapping = new HashMap<Integer, IDeviceController>();
	private HashMap<Integer, IDevice> deviceMapping = new HashMap<Integer, IDevice>();

	private int getNextIndex(Combo combo) {
		if (this.connectivities.getItemCount() > 0) {
			return combo.getItemCount();
		}
		return 0;
	}

	private void addDeviceControllerToMap(IDeviceController iDeviceController) {
		int i = this.getNextIndex(this.connectivities);
		this.indexIDeviceControllerMapping.put(i, iDeviceController);
		this.connectivities.add(iDeviceController.getName(), i);
	}

	private void addDeviceToMap(IDevice iDevice) {
		int i = this.getNextIndex(devices);
		this.deviceMapping.put(i, iDevice);
		this.devices.add(iDevice.getName(), i);
	}

	private IDevice getSelectedDevice() {
		return this.deviceMapping.get(this.devices.getSelectionIndex());
	}

	private IDeviceController getSelectedController() {
		return indexIDeviceControllerMapping.get(connectivities
				.getSelectionIndex());
	}

	protected void initData() {
		this.clearDeviceList();

		for (IDeviceController iDeviceController : this.connectivityDeviceController
				.readAll()) {
			this.addDeviceControllerToMap(iDeviceController);
			iDeviceController.registerDeviceControllerCallback(this);
		}
		this.trackNo.setSelection(this.trackController.getNextTrackNo());
	}

	public TrackForm(Composite parent, int style,
			TrackController ageClassController,
			ConnectivityDeviceController connectivityDeviceController) {
		this(parent, style, ageClassController, connectivityDeviceController,
				new Track());
	}

	/**
	 * @wbp.parser.constructor
	 */
	public TrackForm(Composite parent, int style,
			final TrackController trackController,
			ConnectivityDeviceController connectivityDeviceController,
			Track track) {
		super(parent, style);
		{
			this.connectivityDeviceController = connectivityDeviceController;
			this.trackToWorkOn = track;
			this.trackController = trackController;
		}
		this.shell = parent;
		this.center.setLayout(new GridLayout(4, false));

		Label lblName = new Label(this.center, SWT.NONE);
		lblName.setText("Track No.");

		trackNo = new Spinner(this.center, SWT.BORDER);
		trackNo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
				3, 1));
		trackNo.setIncrement(1);

		Label lblNewLabel = new Label(this.center, SWT.NONE);
		lblNewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblNewLabel.setText("Device");

		connectivities = new Combo(this.center, SWT.NONE);
		connectivities.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 1, 1));
		connectivities.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				readDevices();
			}
		});

		devices = new Combo(this.center, SWT.NONE);
		devices.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (devices.getSelectionIndex() == START_DISCOVERY_INDEX) {
					getSelectedController().startDiscovery();
				}
			}
		});
		devices.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 1));

		Button Pair = new Button(this.center, SWT.NONE);
		Pair.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				getSelectedDevice().rumble();
			}
		});
		Pair.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1,
				1));
		Pair.setText("Pair");

		Composite composite = new Composite(this.center, SWT.NONE);
		composite.setLayout(new FormLayout());
		composite.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false,
				false, 4, 1));

		this.initData();
	}

	private void clearDeviceList() {
		this.devices.removeAll();
		this.devices.add("Start Discovery", 0);
	}

	public void finishedDiscovery() {
		this.shell.getDisplay().asyncExec(new Runnable() {
			public void run() {
				readDevices();				
			}
		});
		
	}

	private void readDevices() {
		this.clearDeviceList();
		for (IDevice device : this.getSelectedController().getAllDevices()) {
			this.addDeviceToMap(device);
		}
	}

	@Override
	protected void okClicked() {
		try {
			trackToWorkOn.setTrackNumber(trackNo.getSelection());
			trackToWorkOn.setStopperDevice(getSelectedDevice());

			trackController.createOrUpdate(trackToWorkOn);
			close();
		} catch (ConstraintViolationException constraintViolationException) {
			showError(constraintViolationException);
		} catch (Exception e) {

		}
	}
}
